"""
# Author : YuuSoo
# version : python 3.8
# Time : 2023/1/6 22:08
"""
# 程序所用扩展包
import numpy as np
from py2neo import *
import yaml
# ==================================================================

# ==================================================================
# import ......
import logging
import flask_restful
# 自定义模块
from errors import my_abort, generate_response, ResponseCode

# 自定义错误
flask_restful.abort = my_abort
root_logger = logging.getLogger('root')
logger = logging.getLogger('main')


# ==================================================================


# ==================================================================
def function(PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums):
    datas = [[]]
    # pklPath = current_app.config['PKL_PATH'] #建议把pklPath作为函数参数传入

    try:  # 简单搞一个粗放型的错误控制，TODO建议predict_*子函数通过抛出自定义异常控制错误代码
        value_qs = function_qs(PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums)
        if value_qs['resp_code'] != 0:
            return value_qs
        datas = value_qs['datas']
        return generate_response(datas)
    except Exception as e:
        return generate_response(datas=datas, code=ResponseCode.ERROR, appendmessage='{0}'.format(str(e)))


def function_qs(PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums):
    res = {}

    logger.info('------------------')
    logger.info('工艺参数推荐开始')
    logger.info('------------------')
    try:
        # model= joblib.load(path_model)
        y_pred = dataProcess(PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums)
        logger.info('工艺参数推荐完成')
        # ......
        return generate_response(y_pred)
    except Exception as e:
        logger.error('工艺参数推荐失败，请检查文件名是否正确')
        res = generate_response(code=ResponseCode.WRONG_PARAM, appendmessage='{0}'.format(str(e)))
    return res


def dataProcess(PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums):
    """设置日志级别"""
    logging.getLogger().setLevel(logging.INFO)

    """读取配置文件，获取配置信息"""
    url, username, password, dataBaseName = readConfig()

    """连接neo4j数据库"""
    graph = login(url, username, password, dataBaseName)
    # """定义模型的输入，PCB板的信息"""
    # PCBThickness = 1.7  # PCB板厚
    # PCBLength = 100  # PCB板长
    # PCBWidth = 100  # PCB板宽
    # Special_Dev = "有"  # 有无特殊温度要求器件
    # RecommendationCount = 10  # 推荐的数量

    """工艺参数推荐"""
    # 转换一下参数类型
    PCBThickness = float(PCBThickness)
    PCBLength = float(PCBLength)
    PCBWidth = float(PCBWidth)
    # RecommendationCount = int(RecommendationCount)
    # if Company == '十所' and Temperature_field_nums == '十温区':
    #     results = recommendate(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev)
    # elif Company == '华仁' and Temperature_field_nums == '八温区':
    #     results = recommendate_huaren(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev)
    # elif Company == '华仁' and Temperature_field_nums == '十温区':
    #     results = recommendate_huaren_10(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev)
    # else:
    #     results = '不存在该公司数据,无法推荐'
    # if Special_Dev == '有' || Special_Dev_B == '有':
    #     results = specailrecommendate(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev,Special_Dev_B,Company,Temperature_field_nums)
    # else:
    #
    results = recommendate(graph,PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums)

    for result in results:
        logger.info(result)

    return results


def login(url, username, password, dataBaseName):
    """
    登陆neo4j
    :param username: 用户名
    :param password: 密码
    :param dataBaseName: 要使用的数据库名字
    :return:graph
    """
    graph = Graph(url, auth=(username, password))
    logging.info("------------------已经登陆数据库成功，正在进行下一步操作...--------------------")
    return graph


def printCalculatorDistance(targetVector, curPrintVector):
    """
    印刷方面计算差异度
    计算两个向量的欧氏距离,由于PCB板厚，PCB板长，PCB板宽不在一个数量级上，
    所以分别给每一列加一个系数，变为同一个数量级，PCB板厚乘10，PCB板长和PCB板宽除10
    :param targetVector: 目标向量
    :param curPrintVector: 当前向量
    :return: 欧氏距离
    """
    resVector = [10 * (targetVector[0] - curPrintVector[0]), (targetVector[1] - curPrintVector[1]) / 10,
                 (targetVector[2] - curPrintVector[2]) / 10]
    return np.sqrt(np.sum(np.square(resVector)))


def weldCalculatorDistance(targetVector, curPrintVector):
    """
    焊接方面计算差异度
    :param targetVector: 目标向量
    :param curPrintVector: 当前向量
    :return:
    """
    # resVector = [0.3 * ((targetVector[0] - curPrintVector[0])/np.linalg.norm(targetVector[0] - curPrintVector[0])), ((targetVector[1] - curPrintVector[1]) /np.linalg.norm(targetVector[1] - curPrintVector[1]))*0.154,
    #              ((targetVector[2] - curPrintVector[2]) /np.linalg.norm(targetVector[2] - curPrintVector[2]))*0.169, 0.368 * ((targetVector[3] - curPrintVector[3])/np.linalg.norm(targetVector[2] - curPrintVector[2]))]
    resVector = [10 * (targetVector[0] - curPrintVector[0]), (targetVector[1] - curPrintVector[1]) / 10,
                 (targetVector[2] - curPrintVector[2]) / 10 , 5 * (targetVector[3] - curPrintVector[3])]
    return np.sqrt(np.sum(np.square(resVector)))

def weldCalculatorDistance_spe(targetVector, curPrintVector):
    """
    焊接方面计算差异度
    :param targetVector: 目标向量
    :param curPrintVector: 当前向量
    :return:
    """
    # resVector = [0.3 * ((targetVector[0] - curPrintVector[0])/np.linalg.norm(targetVector[0] - curPrintVector[0])), ((targetVector[1] - curPrintVector[1]) /np.linalg.norm(targetVector[1] - curPrintVector[1]))*0.154,
    #              ((targetVector[2] - curPrintVector[2]) /np.linalg.norm(targetVector[2] - curPrintVector[2]))*0.169, 0.368 * ((targetVector[3] - curPrintVector[3])/np.linalg.norm(targetVector[2] - curPrintVector[2]))]

    resVector = [10 * (targetVector[0] - curPrintVector[0]), (targetVector[1] - curPrintVector[1] )/ 10 ]
    print(resVector)

    return np.sqrt(np.sum(np.square(resVector)))


def selfSort(a, b):
    """
    自定义排序
    :param a:
    :param b:
    :return:
    """
    return a["differenceRate"] - b["differenceRate"]


def WeldRecommendations(graph, PCBThickness, PCBLength, PCBWidth,BGA_status_A, Special_Dev,Company,Temperature_field_nums,RecommendationCount, paceT=0.1,
                        paceL=10, paceW=10):
    """
    焊接工艺参数推荐
    :param graph:
    :param PCBThickness: PCB板厚
    :param PCBLength: PCB板长
    :param PCBWidth: PCB板宽
    :param Special_Dev: 有无特殊温度要求器件  0为无，  1为有
    :param RecommendationCount: 要推荐的数量
    :param paceT: PCB板厚的步幅
    :param paceL: PCB板长的步幅
    :param paceW: PCB板宽的步幅
    :return:
            所有焊接工艺参数
    """

    logging.info("---------------开始进行回流焊接工艺参数的推荐...------------------")

    """定义一个数组，将符合条件的结果存储起来"""
    printResults = []
    tuhao = Company+Temperature_field_nums

    """进行匹配, 根据范围进行初步筛选接近的推荐信息"""
    while (len(printResults) <= RecommendationCount):
        # cypherRec = "match (ten:$Th {name:'$Th'})-[:include]->(z:装配图号) where z.PCBThickness >= $Ts and z.PCBThickness <= $Tl and z.PCBLength >= $Ls and z.PCBLength <= $Ll and z.PCBWidth >= $Ws and z.PCBWidth <= $Wl and z.PCBDeck = $PD return z;"
        # printResults = graph.run(cypherRec,Th = tuhao,Ts=PCBThickness - paceT, Tl=PCBThickness + paceT, Ls=PCBLength - paceL,
        #                          Ll=PCBLength + paceL,
        #                          Ws=PCBWidth - paceW, Wl=PCBWidth + paceW, PD=PCBDeck).to_table()  # PCBThickness: 0.9
        cypherRec = "MATCH (ten:{tuhao})-[:include]->(z:装配图号) WHERE z.PCBThickness >= {Ts} AND z.PCBThickness <= {Tl} AND z.PCBLength >= {Ls} " \
                    "AND z.PCBLength <= {Ll} AND z.PCBWidth >= {Ws} AND z.PCBWidth <= {Wl}  RETURN z ;"
        printResults = graph.run(
            cypherRec.format(tuhao=tuhao, Ts=PCBThickness - paceT, Tl=PCBThickness + paceT, Ls=PCBLength - paceL,
                             Ll=PCBLength + paceL, Ws=PCBWidth - paceW, Wl=PCBWidth + paceW)).to_table()

        # cypherRec = "match (ten:十所十温区)-[:include]->(z:装配图号) where z.PCBThickness >= $Ts and z.PCBThickness <= $Tl and z.PCBLength >= $Ls and z.PCBLength <= $Ll and z.PCBWidth >= $Ws and z.PCBWidth <= $Wl and z.PCBDeck = $PD return z;"
        # printResults = graph.run(cypherRec, tuhao = tuhao,Ts=PCBThickness - paceT, Tl=PCBThickness + paceT, Ls=PCBLength - paceL,
        #                                  Ll=PCBLength + paceL,
        #                                  Ws=PCBWidth - paceW, Wl=PCBWidth + paceW, PD=PCBDeck).to_table()  # PCBThickness: 0.9

        paceT = paceT + 0.1
        paceL = paceL + 5
        paceW = paceW + 5


    """计算差异度，取出相似度最大的前十位"""
    differenceTopCounts = []  # 取出前RecommendationCount的板子
    targetVector = np.array([PCBThickness, PCBLength, PCBWidth, Special_Dev])  # 目标PCB板的向量
    for printResult in printResults:


        """当前向量"""
        curPrintVector = np.array(
            [printResult[0]["PCBThickness"], printResult[0]["PCBLength"], printResult[0]["PCBWidth"],
             printResult[0]["Special_Dev"]])

        """当前向量与目标向量的差异度距离"""
        distance = weldCalculatorDistance(targetVector, curPrintVector)
        # print(distance)

        """索引出每个图号名字对应的工艺参数组合"""
        JobName = printResult[0]["name"]
        # print(JobName)
        cypher = "match (z:`装配图号`{name:$name})-[r1:effect]-(p:`工艺`{name:'回流焊接工艺'}),(p:`工艺`{name:'回流焊接工艺'})-[r2:include]-(g:`工艺参数`) " \
                 " return g "
                # "where z.PCBDeck=$PCBDeck "
        ProParameters = graph.run(cypher, name=printResult[0]["name"]).to_table()
        # print(ProParameters)
        DownJiaRePower = ProParameters[0][0]["DownJiaRePower"]  # 下加热区功率
        coolerPower = ProParameters[1][0]["coolerPower"]  # 冷却区功率
        UpJiaRePower = ProParameters[2][0]["UpJiaRePower"]  # 上加热区功率
        N2_Con = ProParameters[3][0]["N2_Con"]  # 氧气浓度
        With_speed = ProParameters[4][0]["With_speed"]  # 带速
        Warm_zone10 = ProParameters[5][0]["Warm_zone10"]  # 温区十温度
        Warm_zone9 = ProParameters[6][0]["Warm_zone9"]  # 温区九温度
        Warm_zone8 = ProParameters[7][0]["Warm_zone8"]  # 温区八温度
        Warm_zone7 = ProParameters[8][0]["Warm_zone7"]  # 温区七温度
        Warm_zone6 = ProParameters[9][0]["Warm_zone6"]  # 温区六温度
        Warm_zone5 = ProParameters[10][0]["Warm_zone5"]  # 温区五温度
        Warm_zone4 = ProParameters[11][0]["Warm_zone4"]  # 温区四温度
        Warm_zone3 = ProParameters[12][0]["Warm_zone3"]  # 温区三温度
        Warm_zone2 = ProParameters[13][0]["Warm_zone2"]  # 温区二温度
        Warm_zone1 = ProParameters[14][0]["Warm_zone1"]  # 温区一温度


        # """转换一下PCB板面的值"""
        # PCBDeck = printResult[0]["PCBDeck"]
        # if PCBDeck == 0:
        #     PCBDeck = "A"
        # elif PCBDeck == 1:
        #     PCBDeck = "B"
        # else:
        #     PCBDeck = "A"

        """转换一下有无特殊温度要求器件的值"""
        Special_Dev = printResult[0]["Special_Dev"]
        if Special_Dev == 0:
            Special_Dev = "无"
        else:
            Special_Dev = "有"

        """将结果以字典的形式存储"""
        elementTemp = {"name": JobName, "differenceRate": distance,
                       "PCBLength": printResult[0]["PCBLength"], "PCBThickness": printResult[0]["PCBThickness"],
                       "PCBWidth": printResult[0]["PCBWidth"], "Special_Dev": Special_Dev,
                       "Warm_zone1": Warm_zone1, "Warm_zone2": Warm_zone2,
                       "Warm_zone3": Warm_zone3, "Warm_zone4": Warm_zone4, "Warm_zone5": Warm_zone5,
                       "Warm_zone6": Warm_zone6, "Warm_zone7": Warm_zone7, "Warm_zone8": Warm_zone8,
                       "Warm_zone9": Warm_zone9, "Warm_zone10": Warm_zone10,"With_speed": With_speed, "N2_Con": N2_Con,
                       "UpJiaRePower": UpJiaRePower, "coolerPower": coolerPower, "DownJiaRePower": DownJiaRePower
                       }
        """将结果存储到数组中"""
        differenceTopCounts.append(elementTemp)

    """引入自定义排序所需要的包"""
    import functools

    """将差异度结果进行排序"""
    differenceTopCounts.sort(key=functools.cmp_to_key(selfSort))
    # print(similarTopCount)

    """取出前RecommendationCount的结果"""
    differenceTopCounts = differenceTopCounts[0:RecommendationCount]
    #print(differenceTopCounts)
    return differenceTopCounts


def specailWeldrecommendate(graph, PCBThickness, PCBLength, PCBWidth, BGA_status_A,Special_Dev, Temperature,RecommendationCount, paceT=0.1,
                        paceL=10):
    logging.info("---------------开始进行特殊温度的回流焊接工艺参数的推荐...------------------")

    """定义一个数组，将符合条件的结果存储起来"""
    printResults = []

    """进行匹配, 根据范围进行初步筛选接近的推荐信息"""
    while (len(printResults) <= RecommendationCount):
        cypherRec = "MATCH (ten:`标准温度曲线`)-[:include]->(z:`序号_1`) " \
                    "WHERE z.Temperature >= $Ls AND z.Temperature <= $Ll AND z.PCBThickness >= $Ts AND z.PCBThickness <= $Tl " \
                    "RETURN z"
        printResults = graph.run(cypherRec, Ts=float(PCBThickness) - paceT, Tl=float(PCBThickness) + paceT, Ls=float(Temperature) - paceL,
                                 Ll=float(Temperature)).to_table()  # PCBThickness: 0.9
        # printResults = graph.run(cypherRec, Ts=PCBThickness - paceT, Tl=PCBThickness+ paceT, Ls=Temperature - paceL,
        #                          Ll=Temperature + paceL,).to_table()  # PCBThickness: 0.9

        paceT = paceT + 0.1
        paceL = paceL + 5
    #print(printResults)

    """计算差异度，取出相似度最大的前十位"""
    differenceTopCounts = []  # 取出前RecommendationCount的板子
    targetVector = np.array([float(PCBThickness), float(Temperature)])  # 目标PCB板的向量

    for printResult in printResults:

        """当前向量"""
        curPrintVector = np.array(
            [printResult[0]["PCBThickness"], printResult[0]["Temperature"]])

        """当前向量与目标向量的差异度距离"""
        distance = weldCalculatorDistance_spe(targetVector, curPrintVector)
        #print(distance)

        """索引出每个图号名字对应的工艺参数组合"""
        JobName = printResult[0]["name"]
        #print(JobName)
        cypher = "match (z:`序号_1`{name:$name})-[r1:effect]-(p:`工艺_1`{name:'回流焊接工艺'}),(p:`工艺_1`{name:'回流焊接工艺'})-[r2:include]-(g:`工艺参数_1`) return g"

        ProParameters = graph.run(cypher, name=printResult[0]["name"]).to_table()

        DownJiaRePower = ProParameters[0][0]["DownJiaRePowe_1"]  # 下加热区功率
        coolerPower = ProParameters[1][0]["coolerPower_1"]  # 冷却区功率
        UpJiaRePower = ProParameters[2][0]["UpJiaRePower_1"]  # 上加热区功率
        N2_Con = ProParameters[3][0]["N2_Con_1"]  # 氧气浓度
        With_speed = ProParameters[4][0]["With_speed_1"]  # 带速
        Warm_zone10 = ProParameters[5][0]["Warm_zone10_1"]  # 温区十温度
        Warm_zone9 = ProParameters[6][0]["Warm_zone9_1"]  # 温区九温度
        Warm_zone8 = ProParameters[7][0]["Warm_zone8_1"]  # 温区八温度
        Warm_zone7 = ProParameters[8][0]["Warm_zone7_1"]  # 温区七温度
        Warm_zone6 = ProParameters[9][0]["Warm_zone6_1"]  # 温区六温度
        Warm_zone5 = ProParameters[10][0]["Warm_zone5_1"]  # 温区五温度
        Warm_zone4 = ProParameters[11][0]["Warm_zone4_1"]  # 温区四温度
        Warm_zone3 = ProParameters[12][0]["Warm_zone3_1"]  # 温区三温度
        Warm_zone2 = ProParameters[13][0]["Warm_zone2_1"]  # 温区二温度
        Warm_zone1 = ProParameters[14][0]["Warm_zone1_1"]  # 温区一温度

        """转换一下有无特殊温度要求器件的值"""
        Special_Dev = printResult[0]["Special_Dev"]
        if Special_Dev == 0:
            Special_Dev = "无"
        else:
            Special_Dev = "有"

        """将结果以字典的形式存储"""
        elementTemp = {"name": JobName, "differenceRate": distance,
                       "PCBLength": printResult[0]["PCBLength"], "PCBThickness": printResult[0]["PCBThickness"],
                       "PCBWidth": printResult[0]["PCBWidth"], "Special_Dev": Special_Dev,
                       "Warm_zone1": Warm_zone1, "Warm_zone2": Warm_zone2,
                       "Warm_zone3": Warm_zone3, "Warm_zone4": Warm_zone4, "Warm_zone5": Warm_zone5,
                       "Warm_zone6": Warm_zone6, "Warm_zone7": Warm_zone7, "Warm_zone8": Warm_zone8,
                       "Warm_zone9": Warm_zone9, "Warm_zone10": Warm_zone10, "With_speed": With_speed,
                       "N2_Con": N2_Con,
                       "UpJiaRePower": UpJiaRePower, "coolerPower": coolerPower, "DownJiaRePower": DownJiaRePower
                       }
        """将结果存储到数组中"""
        differenceTopCounts.append(elementTemp)

    """引入自定义排序所需要的包"""
    import functools

    """将差异度结果进行排序"""
    differenceTopCounts.sort(key=functools.cmp_to_key(selfSort))
    # print(similarTopCount)

    """取出前RecommendationCount的结果"""
    differenceTopCounts = differenceTopCounts[0:RecommendationCount]
    # print(differenceTopCounts)
    return differenceTopCounts
def printRecommendations(graph, PCBThickness, PCBLength, PCBWidth,Company,Temperature_field_nums, RecommendationCount, paceT=0.1, paceL=10,
                         paceW=10):
    """
    印刷工艺参数推荐
    :param graph: graph操作
    :param PCBThickness: PCB板厚
    :param PCBLength: PCB板长
    :param PCBWidth: PCB板宽
    :param RecommendationCount: 要求推荐的数量
    :param paceT: PCB板厚的步幅
    :param paceL: PCB板长的步幅
    :param paceW: PCB板宽的步幅
    :return: 印刷工艺参数：differenceTopCounts
            BladeLength ——> 刮刀长度
            BladePressure ——> 刮刀压力
            PrintSpeed ——> 印刷速度
            DemSpeed ——> 脱模速度
            ...
             PCBDeck
    """


    logging.info("--------------开始进行印刷工艺参数的推荐...------------------")

    """定义一个数组，将符合条件的结果存储起来"""
    printResults = []
    tuhao = Company+Temperature_field_nums

    """进行匹配, 根据范围进行初步筛选接近的推荐信息"""
    while (len(printResults) <= RecommendationCount):
        # cypherRec = "match (ten:华仁八温区 {name:'华仁八温区'})-[:include]->(z:装配图号) where z.PCBThickness >= $Ts and z.PCBThickness <= $Tl and z.PCBLength >= $Ls and z.PCBLength <= $Ll and z.PCBWidth >= $Ws and z.PCBWidth <= $Wl and z.PCBDeck = $PD return z;"
        # printResults = graph.run(cypherRec, Ts=PCBThickness - paceT, Tl=PCBThickness + paceT, Ls=PCBLength - paceL,
        #                          Ll=PCBLength + paceL,
        #                          Ws=PCBWidth - paceW, Wl=PCBWidth + paceW, PD=PCBDeck).to_table()  # PCBThickness: 0.9
        cypherRec = "MATCH (ten:{tuhao})-[:include]->(z:装配图号) WHERE z.PCBThickness >= {Ts} AND z.PCBThickness <= {Tl} AND z.PCBLength >= {Ls} AND z.PCBLength <= {Ll} AND z.PCBWidth >= {Ws} AND z.PCBWidth <= {Wl}  RETURN z;"
        printResults = graph.run(
            cypherRec.format(tuhao=tuhao, Ts=PCBThickness - paceT, Tl=PCBThickness + paceT, Ls=PCBLength - paceL,
                             Ll=PCBLength + paceL, Ws=PCBWidth - paceW, Wl=PCBWidth + paceW)).to_table()

        # cypherRec = "match (ten:十所十温区)-[:include]->(z:装配图号) where z.PCBThickness >= $Ts and z.PCBThickness <= $Tl and z.PCBLength >= $Ls and z.PCBLength <= $Ll and z.PCBWidth >= $Ws and z.PCBWidth <= $Wl and z.PCBDeck = $PD return z;"
        # printResults = graph.run(cypherRec, Ts=PCBThickness - paceT, Tl=PCBThickness + paceT, Ls=PCBLength - paceL,
        #                                  Ll=PCBLength + paceL,
        #                                  Ws=PCBWidth - paceW, Wl=PCBWidth + paceW, PD=PCBDeck).to_table()  # PCBThickness: 0.9
        paceT = paceT + 0.1
        paceL = paceL + 5
        paceW = paceW + 5
    # print(printResults)

    """计算差异度，取出相似度最大的前十位"""
    differenceTopCounts = []  # 取出前RecommendationCount的板子
    targetVector = np.array([PCBThickness, PCBLength, PCBWidth])  # 目标PCB板的向量
    for printResult in printResults:
        # print(printResult)

        """当前向量"""
        curPrintVector = np.array(
            [printResult[0]["PCBThickness"], printResult[0]["PCBLength"], printResult[0]["PCBWidth"]])
        # print(curPrintVector[2])

        """当前向量与目标向量的差异度距离"""
        distance = printCalculatorDistance(targetVector, curPrintVector)
        # print(distance)

        """索引出每个图号名字对应的工艺参数组合"""
        JobName = printResult[0]["name"]
        # print(JobName)
        cypher = "match (z:`装配图号`{name:$name})-[r1:effect]-(p:`工艺`{name:'印刷工艺'}),(p:`工艺`{name:'印刷工艺'})-[r2:include]-(g:`工艺参数`)  return g"
        ProParameters = graph.run(cypher, name=printResult[0]["name"]).to_table()
        # print(ProParameters)
        DemSpeed = ProParameters[0][0]["DemSpeed"]  # 脱模速度
        PrintSpeed = ProParameters[1][0]["PrintSpeed"]  # 印刷速度
        BladePressure = ProParameters[2][0]["BladePressure"]  # 刮刀压力
        BladeLength = ProParameters[3][0]["BladeLength"]  # 刮刀长度

        # """转换一下PCB板面的值"""
        # PCBDeck = printResult[0]["PCBDeck"]
        # if PCBDeck == 0:
        #     PCBDeck = "A"
        # elif PCBDeck == 1:
        #     PCBDeck = "B"
        # else:
        #     PCBDeck = "A"

        """将结果以字典的形式存储"""
        elementTemp = {"name": JobName, "differenceRate": distance,
                       "PCBLength": printResult[0]["PCBLength"], "PCBThickness": printResult[0]["PCBThickness"],
                       "PCBWidth": printResult[0]["PCBWidth"], "DemSpeed": DemSpeed, "PrintSpeed": PrintSpeed,
                       "BladePressure": BladePressure, "BladeLength": BladeLength}

        """将结果存储到数组中"""
        differenceTopCounts.append(elementTemp)

    """引入自定义排序所需要的包"""
    import functools

    """将差异度结果进行排序"""
    differenceTopCounts.sort(key=functools.cmp_to_key(selfSort))
    #print(similarTopCount)

    """取出前RecommendationCount的结果"""
    differenceTopCounts = differenceTopCounts[0:RecommendationCount]
    print(111111)
    print(differenceTopCounts)

    return differenceTopCounts

def recommendate(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,BGA_status_A,Temperature,Special_Dev_B,BGA_status_B,Temperature_B,Temperature_field_nums
                 ,RecommendationCount=3, paceT=0.1,
                 paceL=10, paceW=10):
    """
    整合印刷参数推荐和焊接参数推荐
    :param graph: 操作数据库
    :param PCBThickness: PCB板厚
    :param PCBLength: PCB板长
    :param PCBWidth: PCB板宽
    :param Special_Dev: 有无特殊温度要求器件
    :param RecommendationCount:要推荐的数量
    :param paceT:PCB板厚度的步幅
    :param paceL:PCB板长度的步幅
    :param paceW:PCB板宽度的步幅
    :return:
    """
    logging.info("----------------工艺参数推荐开始...-----------------")

    """将有无特殊温度要求的器件B面转化为数字"""
    # 0 代表无，1 代表有
    if Special_Dev_B == "有":
        Special_Dev_B = 1
        recommentResults_weld_B = specailWeldrecommendate(graph, PCBThickness, PCBLength, PCBWidth, BGA_status_B,Special_Dev_B,
                                                          Temperature_B, RecommendationCount=RecommendationCount,
                                                          paceT=0.1, paceL=10)
    else:
        Special_Dev_B = 0
        recommentResults_weld_B = WeldRecommendations(graph, PCBThickness, PCBLength, PCBWidth, BGA_status_B,Special_Dev_B, Company,
                                                      Temperature_field_nums,
                                                      RecommendationCount=RecommendationCount, paceT=paceT, paceL=paceL,
                                                      paceW=paceW)

    """将有无特殊温度要求的器件转化为数字"""
    # 0 代表无，1 代表有
    if Special_Dev == "有":
        Special_Dev = 1
        recommentResults_weld_A = specailWeldrecommendate(graph, PCBThickness, PCBLength, PCBWidth, BGA_status_A,Special_Dev,
                                                          Temperature, RecommendationCount=RecommendationCount,
                                                          paceT=0.1, paceL=10)

    else:
        Special_Dev = 0
        recommentResults_weld_A = WeldRecommendations(graph, PCBThickness, PCBLength, PCBWidth, BGA_status_A,Special_Dev, Company,
                                                      Temperature_field_nums,
                                                      RecommendationCount=RecommendationCount, paceT=paceT, paceL=paceL,
                                                      paceW=paceW)



    """一键推荐参数"""

    # recommentResults_weld_A = WeldRecommendations(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,Temperature_field_nums,
    #                                             RecommendationCount=RecommendationCount, paceT=paceT, paceL=paceL,
    #                                             paceW=paceW)
    # recommentResults_weld_B = WeldRecommendations(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev_B,Company,Temperature_field_nums,
    #                                             RecommendationCount=RecommendationCount, paceT=paceT, paceL=paceL,
    #                                             paceW=paceW)
    #
    recommentResults_print_A = printRecommendations(graph, PCBThickness, PCBLength, PCBWidth,Company,Temperature_field_nums,
                                                  RecommendationCount=RecommendationCount)
    recommentResults_print_B = printRecommendations(graph, PCBThickness, PCBLength, PCBWidth,Company,Temperature_field_nums,
                                                  RecommendationCount=RecommendationCount)
    # recommentResults_weld_A = WeldRecommendations(graph, PCBThickness, PCBLength, PCBWidth, Special_Dev,Company,Temperature_field_nums,
    #                                             RecommendationCount=RecommendationCount, paceT=paceT, paceL=paceL,
    #                                             paceW=paceW)
    # recommentResults_print_A = printRecommendations(graph, PCBThickness, PCBLength, PCBWidth,Company,Temperature_field_nums,
    #                                               RecommendationCount=RecommendationCount)

    # """以100作为基数，变差异度为相似度"""
    baseNum = 100
    for recommentResult in recommentResults_print_A:
        recommentResult["similarRate"] = round(
            ((baseNum - 2.5 * recommentResult.pop("differenceRate")) / baseNum * 100), 2)  # 结果保留两位小数
    baseNum = 100
    for recommentResult in recommentResults_print_B:
        recommentResult["similarRate"] = round(
            ((baseNum - 2.5 * recommentResult.pop("differenceRate")) / baseNum * 100), 2)  # 结果保留两位小数
    logging.info("----------------印刷工艺参数推荐结束...-------------------")
    baseNum = 100
    for recommentResult in recommentResults_weld_A:
        recommentResult["similarRate"] = round(
            ((baseNum - 2.5 * recommentResult.pop("differenceRate")) / baseNum * 100), 2)  # 结果保留两位小数
    baseNum = 100
    for recommentResult in recommentResults_weld_B:
        recommentResult["similarRate"] = round(
            ((baseNum - 2.5 * recommentResult.pop("differenceRate")) / baseNum * 100), 2)  # 结果保留两位小数
    logging.info("----------------回流焊工艺参数推荐结束...-------------------")

    print(recommentResults_weld_A,recommentResults_weld_B,recommentResults_print_A,recommentResults_print_B)
    print(type(recommentResults_print_A))
    return recommentResults_weld_A,recommentResults_weld_B,recommentResults_print_A,recommentResults_print_B
    # return recommentResults_weld_A,  recommentResults_print_A


def readConfig():
    """
    读取配置文件
    :return:
    """
    with open('./conf/application.yml', 'r', encoding='utf-8') as f:
        file_content = f.read()
        content = yaml.load(file_content, yaml.FullLoader)
        url = content["neo4j"]["url"]  # 连接地址
        username = content["neo4j"]["username"]  # 用户名
        password = content["neo4j"]["password"]  # 密码
        dataBaseName = content["neo4j"]["dataBaseName"]  # 数据库名
        # 输出日志信息
        logging.info("--------------读取配置文件成功......-------------------")
        return url, username, password, dataBaseName
